; mixer.asm,       v1.0,   (c) hw / img
;
         BITS      32
         GLOBAL    _stereo_mixer_dma_store_8bit
         GLOBAL    _stereo_mixer_dma_store_16bit
         GLOBAL    _stereo_mixer_dma_store_16bit_unsigned
         GLOBAL    _mono_mixer_dma_store_8bit
         GLOBAL    _mono_mixer_dma_store_16bit

         EXTERN    _realmixbuf    ; volatile int
         EXTERN    _tobegadx
         EXTERN    _mix_play      ; volatile int
         EXTERN    _dmasegbase    ; volatile int
         EXTERN    _mix_tempbuff  ; inttable
;         EXTERN    _posttable     ; chartable 0..4095
         EXTERN    _dmadifference ; difference; realmixbuf in autoinit, 2048 otherwise
         EXTERN    _dmaselector

         SECTION   .text


; stereo mixer / 8bit - store mixdata to DMA base
_stereo_mixer_dma_store_8bit:
         push   fs
         pushad
         mov    ax,[_dmaselector]
         mov    fs,ax

;         xor    eax,eax
         mov    edi,[_tobegadx]
;         add    edi,[_dmasegbase]      ; add dma base (if page boundary crossed)

         mov    ecx,[_realmixbuf]
         mov    esi,_mix_tempbuff      ; ADDRESS of (mix_tempbuff)

; used: (eax),ebx,(ecx),edx,(edi),(esi)

.storeloop
         mov    ebx,[esi]               ; get int from mix_tempbuff
         sar    ebx,11                  ; divide by 1024*2 (50% de-ampification)

         cmp    ebx,127                 ; check > 127
         jna    .smds_ok_full           ; if smaller, OK

         cmp    ebx,07fffffffh          ; check negative
         ja     .smds_neg_clipped       ; if, clip there

         mov    bl,127                  ; >127, clip there

.smds_ok_full
         xor    bl,07fh
;         add    ebx,128                 ; signed -> unsigned

.smds_ok_full2
         add    esi,4                  ; dword mixtempbuf: adx+4

         mov    [fs:edi],bl            ; store to data

         inc    edi                    ; char  dma-buffer: adx+1

         dec    ecx
         jnz    .storeloop

         popad
         pop    fs

         ret

.smds_neg_clipped
         cmp    ebx,07fffff80h          ; if < -128
         jae    .smds_ok_full           ; isn't, ok

         mov    bl,0ffh                 ; clip to -128
         jmp    .smds_ok_full2





; stereo mixer /16bit - store mixdata to DMA base
_stereo_mixer_dma_store_16bit:
         push   fs
         pushad
         mov    ax,[_dmaselector]
         mov    fs,ax

;         xor    eax,eax
         mov    edi,[_tobegadx]
;         add    edi,[_dmasegbase]      ; add dma base (if page boundary crossed)

         mov    ecx,[_realmixbuf]
         mov    esi,_mix_tempbuff      ; ADDRESS of (mix_tempbuff)

; used: (eax),ebx,(ecx),edx,(edi),(esi)

.storeloop16
         mov    ebx,[esi]               ; get int from mix_tempbuff
         sar    ebx,4                   ; divide by 1024x2 (50% de-ampification)

         cmp    ebx,32767               ; check > 127
         jna    .smds_ok_full16         ; if smaller, OK

         cmp    ebx,07fffffffh          ; check negative
         ja     .smds_neg_clipped16     ; if, clip there

         mov    ebx,32767               ; >127, clip there

.smds_ok_full16
         xor    ebx,000007fffh
;         add    ebx,128                 ; signed -> unsigned

.smds_ok_full162
         add    esi,4                  ; dword mixtempbuf: adx+4

         mov    [fs:edi],bx            ; store to data

         add    edi,2                  ; char  dma-buffer: adx+1

         dec    ecx
         jnz    .storeloop16

         popad
         pop    fs

         ret

.smds_neg_clipped16
         cmp    ebx,07fff8000h          ; if < -128
         jae    .smds_ok_full16         ; isn't, ok

         mov    ebx,0ffffh              ; clip to -128
         jmp    .smds_ok_full162













; mono mixer /16bit - store mixdata to DMA base 1
_mono_mixer_dma_store_16bit:
         push   fs
         pushad
         mov    ax,[_dmaselector]
         mov    fs,ax

;         xor    eax,eax
         mov    edi,[_tobegadx]
;         add    edi,[_dmasegbase]      ; add dma base (if page boundary crossed)

         mov    ecx,[_realmixbuf]
         mov    esi,_mix_tempbuff      ; ADDRESS of (mix_tempbuff)

; used: (eax),ebx,(ecx),edx,(edi),(esi)

.storeloop16
         mov    ebx,[esi]               ; get int from mix_tempbuff
         sal    ebx,1                   ; divide by 1024

         cmp    ebx,32767               ; check > 127
         jna    .mmds_ok_full16         ; if smaller, OK

         cmp    ebx,07fffffffh          ; check negative
         ja     .mmds_neg_clipped16     ; if, clip there

         mov    ebx,32767               ; >127, clip there

.mmds_ok_full16
         xor    ebx,000007fffh
;         add    ebx,128                 ; signed -> unsigned

.mmds_ok_full162
         add    esi,4                  ; dword mixtempbuf: adx+4

         mov    [fs:edi],bx            ; store to data

         add    edi,2                  ; char  dma-buffer: adx+1

         dec    ecx
         jnz    .storeloop16

         popad
         pop    fs

         ret

.mmds_neg_clipped16
         cmp    ebx,07fff8000h          ; if < -128
         jae    .mmds_ok_full16         ; isn't, ok

         mov    ebx,0ffffh              ; clip to -128
         jmp    .mmds_ok_full162


;************************************************************************
_stereo_mixer_dma_store_16bit_unsigned:
         push   fs
         pushad
         mov    ax,[_dmaselector]
         mov    fs,ax

;         xor    eax,eax
         mov    edi,[_tobegadx]
;         add    edi,[_dmasegbase]      ; add dma base (if page boundary crossed)

         mov    ecx,[_realmixbuf]
         mov    esi,_mix_tempbuff      ; ADDRESS of (mix_tempbuff)

; used: (eax),ebx,(ecx),edx,(edi),(esi)

.storeloop16u
         mov    ebx,[esi]               ; get int from mix_tempbuff
         sar    ebx,4                   ; divide by 1024x2 (50% de-ampification)

         cmp    ebx,32767               ; check > 127
         jna    .smds_ok_full16u        ; if smaller, OK

         cmp    ebx,07fffffffh          ; check negative
         ja     .smds_neg_clipped16u    ; if, clip there

         mov    ebx,32767               ; >127, clip there

.smds_ok_full16u
         xor    ebx,000007fffh
;         add    ebx,128                 ; signed -> unsigned

.smds_ok_full162u
         add    esi,4                  ; dword mixtempbuf: adx+4

         xor    ebx,0x7fff              ; change to signed

         mov    [fs:edi],bx            ; store to data

         add    edi,2                  ; char  dma-buffer: adx+1

         dec    ecx
         jnz    .storeloop16u

         popad
         pop    fs

         ret

.smds_neg_clipped16u
         cmp    ebx,07fff8000h          ; if < -128
         jae    .smds_ok_full16u        ; isn't, ok

         mov    ebx,0ffffh              ; clip to -128
         jmp    .smds_ok_full162u
;************************************************************************










; mono mixer / 8bit - store mixdata to DMA base 1
_mono_mixer_dma_store_8bit:
         push   fs
         pushad
         mov    ax,[_dmaselector]
         mov    fs,ax

;         xor    eax,eax
         mov    edi,[_tobegadx]
;         add    edi,[_dmasegbase]      ; add dma base (if page boundary crossed)

         mov    ecx,[_realmixbuf]
         mov    esi,_mix_tempbuff      ; ADDRESS of (mix_tempbuff)

; used: (eax),ebx,(ecx),edx,(edi),(esi)

.storeloop
         mov    ebx,[esi]               ; get int from mix_tempbuff
         sar    ebx,6                   ; divide by 1024

         cmp    ebx,127                 ; check > 127
         jna    .mmds_ok_full           ; if smaller, OK

         cmp    ebx,07fffffffh          ; check negative
         ja     .mmds_neg_clipped       ; if, clip there

         mov    bl,127                  ; >127, clip there

.mmds_ok_full
         xor    bl,07fh
;         add    ebx,128                 ; signed -> unsigned

.mmds_ok_full2
         add    esi,4                  ; dword mixtempbuf: adx+4

         mov    [fs:edi],bl            ; store to data

         inc    edi                    ; char  dma-buffer: adx+1

         dec    ecx
         jnz    .storeloop

         popad
         pop    fs

         ret

.mmds_neg_clipped
         cmp    ebx,07fffff80h          ; if < -128
         jae    .mmds_ok_full           ; isn't, ok

         mov    bl,0ffh                 ; clip to -128
         jmp    .mmds_ok_full2


; -------------------------------------

;_putnormalpic:
;         push   ebp                    ; required only in parameters!
;	 mov    ebp,esp                ; required only in parameters!
;
;
;         mov    esp,ebp                ; required only in parameters!
;	 pop    ebp                    ; required only in parameters!
;
;         ret

